// 事件中心接口，用于定义事件中心的行为和属性
interface EventBus {
    // 存储事件名称与事件处理函数数组的映射
    listeners: Map<string, ((...args: any[]) => void)[]>;

    /**
     * 注册事件处理函数
     * @param eventName 事件名称
     * @param callback 事件处理函数，当事件触发时会被调用
     */
    on(eventName: string, callback: (...args: any[]) => void): void;

    /**
     * 移除特定的事件处理函数
     * @param eventName 事件名称
     * @param callback 要移除的事件处理函数
     */
    off(eventName: string, callback: (...args: any[]) => void): void;

    /**
     * 触发事件，调用所有注册的事件处理函数
     * @param eventName 事件名称
     * @param args 传递给事件处理函数的参数
     */
    emit(eventName: string, ...args: any[]): void;
}

// 创建并配置事件中心的实例
const eventBus: EventBus = {
    // 初始化事件监听器映射表
    listeners: new Map<string, ((...args: any[]) => void)[]>(),

    /**
     * 注册事件处理函数
     * @param eventName 事件名称
     * @param callback 事件处理函数
     */
    on(eventName: string, callback: (...args: any[]) => void) {
        // 如果事件名称不存在于监听器中，则创建一个空的事件处理函数数组
        if (!this.listeners.has(eventName)) {
            this.listeners.set(eventName, []);
        }
        // 将事件处理函数添加到对应事件名称的数组中
        this.listeners.get(eventName)?.push(callback);
    },

    /**
     * 移除特定的事件处理函数
     * @param eventName 事件名称
     * @param callback 要移除的事件处理函数
     */
    off(eventName: string, callback: (...args: any[]) => void) {
        // 获取事件名称对应的事件处理函数数组
        const callbacks = this.listeners.get(eventName);
        // 如果事件处理函数数组存在，则移除指定的事件处理函数
        if (callbacks) {
            this.listeners.set(
                eventName,
                callbacks.filter((cb) => cb !== callback)
            );
        }
    },

    /**
     * 触发事件，调用所有注册的事件处理函数
     * @param eventName 事件名称
     * @param args 传递给事件处理函数的参数
     */
    emit(eventName: string, ...args: any[]) {
        // 获取事件名称对应的事件处理函数数组
        const callbacks = this.listeners.get(eventName);
        // 如果事件处理函数数组存在，则调用每一个事件处理函数
        if (callbacks) {
            callbacks.forEach((callback) => callback(...args));
        }
    }
};

// 导出事件中心实例，使其可以在其他模块中使用
export default eventBus;
